# -*- coding: utf8 -*-
from datetime import date

import oss2
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest

import os
import json

from alibabacloud_alimt20181012.client import Client as alimt20181012Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_alimt20181012 import models as alimt_20181012_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
import packaging.version as pkg_version
import pytest
import time
import threading

import nls  # https://article.itxueyuan.com/BJqvaD

#  https://blog.csdn.net/a1150162163/article/details/130068454

URL = "wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1"
TOKEN = "175229e3c9ad4bcb994c722cd7b89c2f"  # 参考https://help.aliyun.com/document_detail/450255.html获取token
APPKEY = "qoJMhXQVMj1ZdxrY"  # 获取Appkey请前往控制台：https://nls-portal.console.aliyun.com/applist


# TEXT = '大壮正想去摘取花瓣，谁知阿丽和阿强突然内讧,谁知阿丽和阿强突然内讧，阿丽拿去手枪向树干边的阿强射击，两声枪响，阿强直接倒入水中'


# 以下代码会根据上述TEXT文本反复进行语音合成
class TestTts:
    def __init__(self, tid, test_file):
        self.__th = threading.Thread(target=self.__test_run)
        self.__id = tid
        self.__test_file = test_file

    def start(self, text):
        self.__text = text
        self.__f = open(self.__test_file, "wb")
        self.__th.start()

    def test_on_metainfo(self, message, *args):
        print("on_metainfo message=>{}".format(message))

    def test_on_error(self, message, *args):
        print("on_error args=>{}".format(args))

    def test_on_close(self, *args):
        print("on_close: args=>{}".format(args))
        try:
            self.__f.close()
        except Exception as e:
            print("close file failed since:", e)

    def test_on_data(self, data, *args):
        try:
            self.__f.write(data)
        except Exception as e:
            print("write data failed:", e)

    def test_on_completed(self, message, *args):
        print("on_completed:args=>{} message=>{}".format(args, message))

    def __test_run(self):
        print("thread:{} start..".format(self.__id))
        tts = nls.NlsSpeechSynthesizer(url=URL,
                                       token=TOKEN,
                                       appkey=APPKEY,
                                       on_metainfo=self.test_on_metainfo,
                                       on_data=self.test_on_data,
                                       on_completed=self.test_on_completed,
                                       on_error=self.test_on_error,
                                       on_close=self.test_on_close,
                                       callback_args=[self.__id])
        print("{}: session start".format(self.__id))
        r = tts.start(self.__text, voice="ailun", aformat='wav')
        print("{}: tts done with result:{}".format(self.__id, r))


# def multiruntest(num=500):
#     for i in range(0, num):
#


# nls.enableTrace(True)
# multiruntest(1)


def create_client(
        access_key_id: str,
        access_key_secret: str,
) -> alimt20181012Client:
    """
    使用AK&SK初始化账号Client
    @param access_key_id:
    @param access_key_secret:
    @return: Client
    @throws Exception
    """
    config = open_api_models.Config(
        # 必填，您的 AccessKey ID,
        access_key_id='LTAI5tDUPZfPbT2AvUdWKGQV',
        # 必填，您的 AccessKey Secret,
        access_key_secret='8o3FmXvpRcaxzMWUZbzn1lD1t06DPa'
    )
    # 访问的域名
    config.endpoint = f'mt.cn-hangzhou.aliyuncs.com'
    return alimt20181012Client(config)


def translate(content):
    # client = create_client(os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
    #                        os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'])
    client = create_client('LTAI5tDUPZfPbT2AvUdWKGQV',
                           '8o3FmXvpRcaxzMWUZbzn1lD1t06DPa')
    translate_general_request = alimt_20181012_models.TranslateGeneralRequest(format_type='text',
                                                                              source_language='en',
                                                                              target_language='zh',
                                                                              source_text=content, scene='general')
    runtime = util_models.RuntimeOptions()
    resp = client.translate_general_with_options(translate_general_request, runtime)
    data = json.loads(UtilClient.to_jsonstring(resp.body))
    return data['Data']['Translated']


def format_time(milliseconds):
    # 计算小时、分钟、秒和毫秒
    hours = milliseconds // (1000 * 60 * 60)
    minutes = (milliseconds // (1000 * 60)) % 60
    seconds = (milliseconds // 1000) % 60
    millis = milliseconds % 1000

    # 格式化时间为字符串
    time_str = "{:02d}:{:02d}:{:02d},{:03d}".format(hours, minutes, seconds, millis)
    return time_str


def generate_srt(subtitles, output_file):
    with open(output_file, "w", encoding="utf-8") as f:
        index = 1
        for subtitle in subtitles:
            start_time = subtitle["start_time"]
            end_time = subtitle["end_time"]
            text = subtitle["text"]

            # 写入字幕序号
            f.write(str(index) + "\n")

            # 写入时间轴
            f.write(f"{start_time} --> {end_time}\n")

            # 写入字幕文本
            f.write(text + "\n\n")

            index += 1


def fileTrans(akId, akSecret, appKey, fileLink):
    # 地域ID，固定值。
    REGION_ID = "cn-shanghai"
    PRODUCT = "nls-filetrans"
    DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
    API_VERSION = "2018-08-17"
    POST_REQUEST_ACTION = "SubmitTask"
    GET_REQUEST_ACTION = "GetTaskResult"
    # 请求参数
    KEY_APP_KEY = "appkey"
    KEY_FILE_LINK = "file_link"
    KEY_VERSION = "version"
    KEY_ENABLE_WORDS = "enable_words"
    # 是否开启智能分轨
    KEY_AUTO_SPLIT = "auto_split"
    # 响应参数
    KEY_TASK = "Task"
    KEY_TASK_ID = "TaskId"
    KEY_STATUS_TEXT = "StatusText"
    KEY_RESULT = "Result"
    # 状态值
    STATUS_SUCCESS = "SUCCESS"
    STATUS_RUNNING = "RUNNING"
    STATUS_QUEUEING = "QUEUEING"
    # 创建AcsClient实例
    client = AcsClient(akId, akSecret, REGION_ID)
    # 提交录音文件识别请求
    postRequest = CommonRequest()
    postRequest.set_domain(DOMAIN)
    postRequest.set_version(API_VERSION)
    # postRequest.set
    postRequest.set_product(PRODUCT)
    postRequest.set_action_name(POST_REQUEST_ACTION)
    postRequest.set_method('POST')
    # 新接入请使用4.0版本，已接入（默认2.0）如需维持现状，请注释掉该参数设置。
    # 设置是否输出词信息，默认为false，开启时需要设置version为4.0。
    task = {KEY_APP_KEY: appKey, KEY_FILE_LINK: fileLink, KEY_VERSION: "4.0", KEY_ENABLE_WORDS: False}
    # 开启智能分轨，如果开启智能分轨，task中设置KEY_AUTO_SPLIT为True。
    # task = {KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", KEY_ENABLE_WORDS : False, KEY_AUTO_SPLIT : True}
    task = json.dumps(task)
    print(task)
    postRequest.add_body_params(KEY_TASK, task)
    taskId = ""
    try:
        postResponse = client.do_action_with_exception(postRequest)
        postResponse = json.loads(postResponse)
        print(postResponse)
        statusText = postResponse[KEY_STATUS_TEXT]
        if statusText == STATUS_SUCCESS:
            print("录音文件识别请求成功响应！")
            taskId = postResponse[KEY_TASK_ID]
        else:
            print("录音文件识别请求失败！")
            return
    except ServerException as e:
        print(e)
    except ClientException as e:
        print(e)
    # 创建CommonRequest，设置任务ID。
    getRequest = CommonRequest()
    getRequest.set_domain(DOMAIN)
    getRequest.set_version(API_VERSION)
    getRequest.set_product(PRODUCT)
    getRequest.set_action_name(GET_REQUEST_ACTION)
    getRequest.set_method('GET')
    getRequest.add_query_param(KEY_TASK_ID, taskId)
    # 提交录音文件识别结果查询请求
    # 以轮询的方式进行识别结果的查询，直到服务端返回的状态描述符为"SUCCESS"、"SUCCESS_WITH_NO_VALID_FRAGMENT"，
    # 或者为错误描述，则结束轮询。
    statusText = ""
    while True:
        try:
            getResponse = client.do_action_with_exception(getRequest)
            getResponse = json.loads(getResponse)
            print(getResponse)
            statusText = getResponse[KEY_STATUS_TEXT]
            if statusText == STATUS_RUNNING or statusText == STATUS_QUEUEING:
                # 继续轮询
                time.sleep(10)
            else:
                return getResponse
        except ServerException as e:
            print(e)
        except ClientException as e:
            print(e)


def extract_filename(file_path):
    file_name = os.path.basename(file_path)
    return file_name.split('.')[0]


# 上传文件到oss
def upOss(localFile):
    auth = oss2.Auth('LTAI4G2FFKwsh3dExGFFzFDs', '6EEBnuJxNOdlB7kxwjFipnFu7pp4Jn')
    bucket = oss2.Bucket(auth, 'https://oss-cn-qingdao.aliyuncs.com', 'dre-five')
    today = date.today()
    destFile = 'carry/' + str(today) + '/' + localFile
    with open(localFile, 'rb') as fileobj:
        bucket.put_object(destFile, fileobj)
    return 'https://dre-five.oss-cn-qingdao.aliyuncs.com/' + destFile


def delete_file(file_path):
    if os.path.exists(file_path):
        os.remove(file_path)
        print(f"文件 {file_path} 已成功删除")
    else:
        print(f"文件 {file_path} 不存在")


def traverse_directory(directory):
    for root, dirs, files in os.walk(directory):
        # 遍历目录中的文件
        for file in files:
            if str(file).endswith('wav'):
                file_path = os.path.join(root, file)
                # 在这里执行文件操作，例如打印文件路径或进行其他处理
                print(file_path)
                ossUrl = upOss(file_path)
                loads = fileTrans(accessKeyId, accessKeySecret, appKey, ossUrl)
                # print(loads)
                srt = []
                cnSrt = []
                dir = 'buff/5_wav/' + extract_filename(file_path)
                os.makedirs(dir, exist_ok=True)
                for i in loads['Result']['Sentences']:
                    BeginTime_ = format_time(i['BeginTime'])
                    EndTime_ = format_time(i['EndTime'])
                    Text_ = i['Text']
                    c = {'start_time': BeginTime_, 'end_time': EndTime_, 'text': Text_}
                    srt.append(c)
                    # fileName = str(i['BeginTime']) + '-' + str(i['EndTime']) + '.wav'
                    translate1 = translate(Text_)
                    # t = TestTts(fileName, dir + '/' + fileName)
                    # t.start(translate1)
                    cn = {'start_time': BeginTime_, 'end_time': EndTime_, 'text': translate1}
                    cnSrt.append(cn)
                # 生成英文字幕文件
                # generate_srt(srt, 'buff/4_ctr_wav/' + extract_filename(file_path) + '.srt')
                # 生成中文字幕文件
                generate_srt(cnSrt, 'buff/4_ctr_wav/' + extract_filename(file_path) + '.srt')
                delete_file(file_path)

if pkg_version.parse(pytest.__version__) >= pkg_version.parse("6.0"):
    os.environ['PATH'] = '/usr/local/bin:' + os.environ['PATH']  # 添加 ffmpeg 路径到环境变量中
    # 指定要遍历的目录路径
    directory_path = 'buff/3_wav_16k'
    accessKeyId = "LTAI5tDUPZfPbT2AvUdWKGQV"
    accessKeySecret = "8o3FmXvpRcaxzMWUZbzn1lD1t06DPa"
    appKey = "EzA6KVNgh4zB18sz"

    traverse_directory(directory_path)
